package com.sx.redis.service.impl;

import com.sx.redis.service.RedisService;
import io.lettuce.core.output.ValueScanOutput;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * @author AdinZ
 * @date 2020/11/7 14:16
 */
@Service
public class RedisServiceImpl implements RedisService {
    private final RedisTemplate redisTemplate;

    public RedisServiceImpl(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public <K, V> V get(K key) {
        ValueOperations<K,V> operations = this.redisTemplate.opsForValue();
        return operations.get(key);
    }

    @Override
    public <K, V> List<V> get(K k,long start,long end) {
        ListOperations<K,V> operations = this.redisTemplate.opsForList();
        return operations.range(k,start,end);
    }

    @Override
    public <K> Set<K> keys(K key) {
        return   this.redisTemplate.keys(key);
    }

    public <K, V> void set(K k, V v) {
        ValueOperations<K,V> operations = this.redisTemplate.opsForValue();
        operations.set(k, v);
    }

    public <K, V> void set(K k, V v, long expire) {
        ValueOperations<K,V> operations = this.redisTemplate.opsForValue();
        operations.set(k, v,expire, TimeUnit.MILLISECONDS);
    }

    public <K> void delete(K k) {
        this.redisTemplate.delete(k);
    }

    public <H, HK, HV> void set(H h, HK hk, HV hv) {
        HashOperations<H,HK,HV> operations = this.redisTemplate.opsForHash();
        operations.put(h, hk, hv);
    }

    @Override
    public <K, V> void set(K k,  Collection<V> v) {
        ListOperations<K, V> operations = this.redisTemplate.opsForList();
        operations.leftPushAll(k,v);
    }

    public <H, HK,HV> HV get(H h, HK hk) {
        HashOperations<H,HK,HV> operations = this.redisTemplate.opsForHash();
        return operations.get(h,hk);
    }

    public <H, HK> void delete(H h, HK... hk) {
        HashOperations<H,HK,Object> operations = this.redisTemplate.opsForHash();
        operations.delete(h,hk);
    }

    public <H, HK, HV> Map<HK, HV> getMap(H h) {
        HashOperations<H,HK,HV> operations = this.redisTemplate.opsForHash();
        return operations.entries(h);
    }

    public <H, HV> List<HV> getMapValue(H h) {
        HashOperations<H,Object,HV> operations = this.redisTemplate.opsForHash();
        return operations.values(h);
    }

    public <H, HK> Set<HK> getMapKeys(H h) {
        HashOperations<H,HK,Object> operations = this.redisTemplate.opsForHash();
        return operations.keys(h);
    }

    @Override
    public <K> long increment(K key, long index) {
        return this.redisTemplate.opsForValue().increment(key,index);
    }

    @Override
    public <K> double increment(K key, double index) {
        return this.redisTemplate.opsForValue().increment(key,index);
    }

    @Override
    public <H, HK> long increment(H h, HK hk, long index) {
        return this.redisTemplate.opsForHash().increment(h,hk,index);
    }

    @Override
    public <H, HK> double increment(H h, HK hk, double index) {
        return this.redisTemplate.opsForHash().increment(h,hk,index);
    }

    @Override
    public <K> boolean lock(K k) {
        Object o = this.get(k);
        if(o!=null) return false;
        this.set(k,k);
        return true;
    }

    @Override
    public <K> void unlock(K k) {
        delete(k);
    }

}
